/** @type {HTMLCanvasElement} */

import { randomNum, langs } from '../util/index.js'
import Stats from '../node_modules/stats.js/src/Stats.js'
import { GUI } from '../node_modules/dat.gui/build/dat.gui.module.js'

const canvas = document.querySelector('#canvas')
const width = window.innerWidth
const height = window.innerHeight
canvas.width = width
canvas.height = height
const ctx = canvas.getContext('2d')

//stats
const stats = new Stats()
stats.showPanel(0)
document.body.appendChild(stats.dom)

const options = {
    rainNum: 20,
    dyMin: 1,
    dyMax: 6,
    fontSize: 17,
    isRandomColor: false,
    colorText: '#55efc4',
    colorShadow: '#3eec4d',
    shadowSize: 2,
    isShadow: false
}

// gui
const gui = new GUI({ width: 320 });
const folder1 = gui.addFolder('基础')
folder1.open()
const controller1 = folder1.add(options, 'rainNum', 20, 400, 1)
const controller2 = folder1.add(options, 'dyMin', 1, 5, 1)
const controller3 = folder1.add(options, 'dyMax', 6, 16, 1)
const controller4 = folder1.add(options, 'fontSize', 4, 30, 1)
const controller41 = folder1.add(options, 'isRandomColor', [true, false])
const controller5 = folder1.addColor(options, 'colorText')
const controller51 = folder1.add(options, 'isShadow', [true, false])
const controller6 = folder1.addColor(options, 'colorShadow')
const controller7 = folder1.add(options, 'shadowSize', 3, 10, 1)

controller1.onFinishChange(() => {
    init()
})
controller4.onFinishChange(() => {
    init()
})

//随机颜色
const colors = ['#55efc4', '#81ecec', '#74b9ff',
    '#a29bfe', '#dfe6e9', '#00b894', '#00cec9', '#0984e3', '#6c5ce7',
    '#b2bec3', '#ffeaa7', '#fab1a0', '#ff7675', '#fd79a8', '#636e72', '#fdcb6e', '#e17055', '#d63031', '#e84393', '#2d3436']

function RainCode() {
    this.x = Math.floor(Math.random() * width)
    this.letterSpace = options.fontSize

    this.init = function () {
        this.y = randomNum(-1000, -300)
        this.str = langs[Math.floor(Math.random() * langs.length)]
        this.dy = randomNum(options.dyMin, options.dyMax)
        this.color = options.isRandomColor?colors[Math.floor(Math.random() * colors.length)]:options.colorText
    }

    this.init()

    this.draw = function () {
        this.str.split('').forEach((char, index) => {
            ctx.font = `${options.fontSize}px Fira Code`
            ctx.fillStyle = this.color
            ctx.fillText(char, this.x, this.y + this.letterSpace * index)

            if (!options.isShadow) return
            ctx.shadowColor = options.colorShadow
            ctx.shadowBlur = options.shadowSize
        })
    }

    this.update = function () {
        this.y += this.dy
        if (this.y > height) {
            this.init()
        }
        this.draw()
    }
}

function animate() {
    stats.begin()

    requestAnimationFrame(animate)
    // ctx.clearRect(0, 0, width, height)
    ctx.fillStyle = 'rgba(0,0,0,0.4)'
    ctx.fillRect(0, 0, width, height)
    rains.forEach(item => {
        item.update()
    })

    stats.end()
}

const rains = []
function init() {
    rains.length = 0
    for (let i = 0; i < options.rainNum; i++) {
        const rain = new RainCode()
        rains.push(rain)
    }
}

init()
animate()